package cn.com.headfree.competent.service.impl;

import cn.com.headfree.base.controller.ResultData;
import cn.com.headfree.callback.call.FileServerCall;
import cn.com.headfree.entity.TEmpBaseInfo;
import cn.com.headfree.entity.TSeniorCompetent;
import cn.com.headfree.entity.TouXiangVo;
import cn.com.headfree.competent.service.WordExportService;
import cn.com.headfree.util.*;
import cn.com.headfree.vo.*;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.data.*;
import com.deepoove.poi.data.style.Style;
import com.deepoove.poi.data.style.TableStyle;
import com.gta.edu.sdk.util.StringUtil;
import feign.Response;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STJc;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 导出word工具类
 */
@Service("wordExportService")
public class WordExportServiceImpl implements WordExportService {

    private static final Logger log = LogManager.getLogger(WordExportServiceImpl.class);

    @Autowired
    private FileServerCall fileServerCall;

    /**
     * 在本地生成word文档
     * @param response
     * @param data              结果对象
     * @param filename            本地生成word名称
     */
    @Override
    public void exportWord(HttpServletResponse response, CompetentReportVo data, String filename , String erpNo){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年M月d日");
        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy年M月");
        FileOutputStream out=null;
        XWPFTemplate template = null;
        InputStream inputStream = null;
        File file = null;
        PaymentData datas = new PaymentData();//数据封装
        //样式
        Style textStyle = new Style();
        TableStyle headStyle = new TableStyle();
        TableStyle rowStyle = new TableStyle();
        rowStyle.setAlign(STJc.Enum.forInt(2));
        textStyle.setFontFamily("仿宋_GB2312");
        textStyle.setFontSize(12);
        textStyle.setColor("000000");
        headStyle.setAlign(STJc.CENTER);

        TEmpBaseInfo baseInfo = data.gettEmpBaseInfo();
        if(baseInfo != null){
            datas.setName(baseInfo.getName());
            datas.setUnit(baseInfo.getUnit());
            datas.setIdCardNo(baseInfo.getIdCardNo());
            datas.setNation(baseInfo.getNation());
            datas.setBornPlace(baseInfo.getBornPlace());
            if(baseInfo.getJobDate() != null){
                datas.setJobDate(sdf1.format(baseInfo.getJobDate()));
            }
        }

        TSeniorCompetent competent = data.gettSeniorCompetent();
        if(competent != null){
            datas.setCurrentSubjLevel(competent.getCurrentSubjLevel());//现专业技术资格
            datas.setReadySubjLevel(competent.getReadySubjLevel());//拟申报专业技术资格
            datas.setBranchSubj(competent.getBranchSubj());//现从事专业
            String currentSubjInfo = "";
            if(competent.getAcquTime() != null){
                currentSubjInfo = sdf.format(competent.getAcquTime());
            }
            if(!StringUtil.isNullOrEmpty(competent.getAuditUnit())){
                currentSubjInfo = currentSubjInfo + "经" + competent.getAuditUnit() + "批准";
            }
            if(!StringUtil.isNullOrEmpty(competent.getCurrentSubjLevel())){
                currentSubjInfo = currentSubjInfo + "取得" + competent.getCurrentSubjLevel() + "资格";
            }
            if(!StringUtil.isNullOrEmpty(competent.getCertNo())){
                currentSubjInfo = currentSubjInfo + "、证书编号：" + competent.getCertNo();
            }
            datas.setCurrentSubjInfo(currentSubjInfo);
            if(competent.getAcquTime() != null){
                datas.setAcquTime(sdf.format(competent.getAcquTime()));
                int currentYear = Calendar.getInstance().get(Calendar.YEAR);//当前年度
                int year = new Integer(String.format("%tY", competent.getAcquTime()));//获取现资格的年度
                int yearCount = currentYear - year;
                int currentMonth = Calendar.getInstance().get(Calendar.MONTH)+1;//当前月份
                int month = new Integer(String.format("%tm", competent.getAcquTime()));//获取现资格的年度
                if(currentMonth > month){
                    yearCount++;
                }
                if(yearCount > 0){
                    datas.setCurrentMajorYear(yearCount+"年");
                }
            }
        }

        WorkStatusTable workStatusTable = new WorkStatusTable();
        //在岗现状
        WorkExpInfoVo workExpInfoVo = data.getWorkExpInfoVo();
        List<RowRenderData> workRowList = new ArrayList<>();
        if(workExpInfoVo != null){
            if(workExpInfoVo.getIsHide() == null || !(workExpInfoVo.getIsHide().equals("0"))) {
                String startTime = "";
                if (workExpInfoVo.getStartTime() != null) {
                    startTime = sdf.format(workExpInfoVo.getStartTime());
                }
                RowRenderData row = RowRenderData.build(
                        new TextRenderData(workExpInfoVo.getDept(), textStyle),
                        new TextRenderData(workExpInfoVo.getPost(), textStyle),
                        new TextRenderData(workExpInfoVo.getRank(), textStyle),
                        new TextRenderData(startTime, textStyle));
                row.setRowStyle(rowStyle);
                workRowList.add(row);
            }
        }
        workStatusTable.settWorkExpStatus(workRowList);
        datas.setWorkStatusTable(workStatusTable);

        //学历、学位情况
        EducateInfoTable educateInfoTable = new EducateInfoTable();
        List<EducateInfoVo> educateInfoVos = data.getEducateInfoVos();
        List<RowRenderData> eduRowList = new ArrayList<>();
        if(educateInfoVos != null && educateInfoVos.size() > 0){
            for(int i=educateInfoVos.size()-1;i>=0;i--){
                if(educateInfoVos.get(i).getIsHide() == null || !(educateInfoVos.get(i).getIsHide().equals("0"))) {
                    String acquTime = "";
                    if (educateInfoVos.get(i).getAcquTime() != null) {
                        acquTime = sdf.format(educateInfoVos.get(i).getAcquTime());
                    }
                    String educName = "";
                    if(educateInfoVos.get(i).getEducName() != null){
                        educName = educateInfoVos.get(i).getEducName();
                    }
                    if(educateInfoVos.get(i).getDegreeName() != null){
                        educName = educName + " " + educateInfoVos.get(i).getDegreeName();
                    }
                    RowRenderData row = RowRenderData.build(
                            new TextRenderData(educateInfoVos.get(i).getEducType(), textStyle),
                            new TextRenderData(educName, textStyle),
                            new TextRenderData(acquTime, textStyle),
                            new TextRenderData(educateInfoVos.get(i).getGradSchool()+educateInfoVos.get(i).getMajor(), textStyle),
                            new TextRenderData(educateInfoVos.get(i).getMajorType(), textStyle));
                    row.setRowStyle(rowStyle);
                    eduRowList.add(row);
                }
            }
        }
        educateInfoTable.setEducateInfos(eduRowList);
        datas.setEducateInfoTable(educateInfoTable);

        //学习培训经历
        StudyTrainTable studyTrainTable = new StudyTrainTable();
        List<StudyAndTrainVo> studyAndTrainVos = data.getStudyAndTrainVos();
        List<RowRenderData> studyRowList = new ArrayList<>();
        if(studyAndTrainVos != null && studyAndTrainVos.size() > 0){
            for(int i=studyAndTrainVos.size()-1;i>=0;i--){
                if(studyAndTrainVos.get(i).getIsHide() == null || !(studyAndTrainVos.get(i).getIsHide().equals("0"))) {
                    String startTime = "";
                    String endTime = "";
                    if (studyAndTrainVos.get(i).getStartTime() != null) {
                        startTime = sdf.format(studyAndTrainVos.get(i).getStartTime());
                    }
                    if (studyAndTrainVos.get(i).getEndTime() != null) {
                        endTime = sdf.format(studyAndTrainVos.get(i).getEndTime());
                    }
                    RowRenderData row = RowRenderData.build(
                            new TextRenderData(startTime+"-"+endTime, textStyle),
                            new TextRenderData(studyAndTrainVos.get(i).getEduLevel(), textStyle),
                            new TextRenderData(studyAndTrainVos.get(i).getSchoolAndUnit(), textStyle),
                            new TextRenderData(studyAndTrainVos.get(i).getMajor(), textStyle),
                            new TextRenderData(studyAndTrainVos.get(i).getSponsor(), textStyle),
                            new TextRenderData(studyAndTrainVos.get(i).getIsGetCert(), textStyle));
                    row.setRowStyle(rowStyle);
                    studyRowList.add(row);
                }
            }
        }
        studyTrainTable.setStudyTrainInfos(studyRowList);
        datas.setStudyTrainTable(studyTrainTable);

        //主要工作经历
        WorkInfoTable workInfoTable = new WorkInfoTable();
        List<WorkExpInfoVo> workExpInfoVos = data.getWorkExpInfoVos();
        List<RowRenderData> workInfoRowList = new ArrayList<>();
        if(workExpInfoVos != null && workExpInfoVos.size() > 0){
            for(int i=workExpInfoVos.size()-1;i>=0;i--){
                if(workExpInfoVos.get(i).getIsHide() == null || !(workExpInfoVos.get(i).getIsHide().equals("0"))) {
                    String startTime = "";
                    String endTime = "";
                    if (workExpInfoVos.get(i).getStartTime() != null) {
                        startTime = sdf.format(workExpInfoVos.get(i).getStartTime());
                    }
                    if (workExpInfoVos.get(i).getEndTime() != null) {
                        endTime = sdf.format(workExpInfoVos.get(i).getEndTime());
                    }
                    RowRenderData row = RowRenderData.build(
                            new TextRenderData(startTime+"-"+endTime, textStyle),
                            new TextRenderData(workExpInfoVos.get(i).getCompany()+workExpInfoVos.get(i).getDept(), textStyle),
                            new TextRenderData(workExpInfoVos.get(i).getPost(), textStyle),
                            new TextRenderData(workExpInfoVos.get(i).getJobContent(), textStyle),
                            new TextRenderData(workExpInfoVos.get(i).getWorkStatus(), textStyle));
                    row.setRowStyle(rowStyle);
                    workInfoRowList.add(row);
                }
            }
        }
        workInfoTable.setWorkInfos(workInfoRowList);
        datas.setWorkInfoTable(workInfoTable);

        //取得现专业技术资格后的工作成果
        WorkResultTable workResultTable = new WorkResultTable();
        //取得现专业技术资格后的工作成果--科技创新管理
        List<TecManInnovVo> tecManInnovVos = data.getTecManInnovVos();
        List<RowRenderData> tecRowList = new ArrayList<>();
        if(tecManInnovVos != null && tecManInnovVos.size() > 0){
            for(int i=tecManInnovVos.size()-1;i>=0;i--){
                if(tecManInnovVos.get(i).getIsHide() == null || !(tecManInnovVos.get(i).getIsHide().equals("0"))) {
                    String awardDate = "";
                    if (tecManInnovVos.get(i).getAwardDate() != null) {
                        awardDate = sdf.format(tecManInnovVos.get(i).getAwardDate());
                    }
                    RowRenderData row = RowRenderData.build(
                            new TextRenderData(awardDate, textStyle),
                            new TextRenderData(tecManInnovVos.get(i).getAchiName(), textStyle),
                            new TextRenderData(tecManInnovVos.get(i).getAchiType(),textStyle),
                            new TextRenderData(tecManInnovVos.get(i).getAwardLevel()+tecManInnovVos.get(i).getAwardGrade(), textStyle),
                            new TextRenderData(tecManInnovVos.get(i).getRank()+"", textStyle),
                            new TextRenderData(tecManInnovVos.get(i).getAwardOrg(), textStyle));
                    row.setRowStyle(rowStyle);
                    tecRowList.add(row);
                }
            }
        }
        workResultTable.setTecManInnovVos(tecRowList);
        //取得现专业技术资格后的工作成果--个人荣誉
        List<HonorDatasVo> honorDatasVos = data.getHonorDatasVos();
        List<RowRenderData> honorRowList = new ArrayList<>();
        if(honorDatasVos != null && honorDatasVos.size() > 0){
            for(int i=honorDatasVos.size()-1;i>=0;i--){
                if(honorDatasVos.get(i).getIsHide() == null || !(honorDatasVos.get(i).getIsHide().equals("0"))) {
                    String acquTime = "";
                    if (honorDatasVos.get(i).getAcquTime() != null) {
                        acquTime = sdf.format(honorDatasVos.get(i).getAcquTime());
                    }
                    RowRenderData row = RowRenderData.build(
                            new TextRenderData(acquTime, textStyle),
                            new TextRenderData(honorDatasVos.get(i).getHonorName(), textStyle),
                            new TextRenderData(honorDatasVos.get(i).getAwardUnit(), textStyle));
                    row.setRowStyle(rowStyle);
                    honorRowList.add(row);
                }
            }
        }
        workResultTable.setHonorDatasVos(honorRowList);
        datas.setWorkResultTable(workResultTable);

        //取得现专业技术资格后的作品成果
        OpusResultTable opusResultTable = new OpusResultTable();
        //取得现专业技术资格后的作品成果--学术成果
        List<AcadeAchiveVo> acadeAchiveVos = data.getAcadeAchiveVos();
        List<RowRenderData> acadeRowList = new ArrayList<>();
        if(acadeAchiveVos != null && acadeAchiveVos.size() > 0){
            for(int i=acadeAchiveVos.size()-1;i>=0;i--){
                if(acadeAchiveVos.get(i).getIsHide() == null || !(acadeAchiveVos.get(i).getIsHide().equals("0"))) {
                    String pubTime = "";
                    if (acadeAchiveVos.get(i).getPubTime() != null) {
                        pubTime = sdf.format(acadeAchiveVos.get(i).getPubTime());
                    }
                    String pubName = "";
                    if("01".equals(acadeAchiveVos.get(i).getAcadType())){//著作使用出版社名称
                        pubName = acadeAchiveVos.get(i).getPublisher();
                    }else{//论文使用刊物名称
                        pubName = acadeAchiveVos.get(i).getPubName();
                    }
                    RowRenderData row = RowRenderData.build(
                            new TextRenderData(pubTime, textStyle),
                            new TextRenderData(acadeAchiveVos.get(i).getAcadName(), textStyle),
                            new TextRenderData(pubName, textStyle),
                            new TextRenderData(acadeAchiveVos.get(i).getPubType(), textStyle),
                            new TextRenderData(acadeAchiveVos.get(i).getMyDuty(), textStyle));
                    row.setRowStyle(rowStyle);
                    acadeRowList.add(row);
                }
            }
        }
        opusResultTable.setAcadeAchiveVos(acadeRowList);
        //取得现专业技术资格后的作品成果--标准制定
        List<StandInfoVo> standInfoVos = data.getStandInfoVos();
        List<RowRenderData> standRowList = new ArrayList<>();
        if(standInfoVos != null && standInfoVos.size() > 0){
            for(int i=standInfoVos.size()-1;i>=0;i--){
                if(standInfoVos.get(i).getIsHide() == null || !(standInfoVos.get(i).getIsHide().equals("0"))) {
                    String issueTime = "";
                    if (standInfoVos.get(i).getIssueTime() != null) {
                        issueTime = sdf.format(standInfoVos.get(i).getIssueTime());
                    }
                    RowRenderData row = RowRenderData.build(
                            new TextRenderData(issueTime, textStyle),
                            new TextRenderData(standInfoVos.get(i).getName(), textStyle),
                            new TextRenderData(standInfoVos.get(i).getMyDuty(), textStyle));
                    row.setRowStyle(rowStyle);
                    standRowList.add(row);
                }
            }
        }
        opusResultTable.setStandInfoVos(standRowList);
        datas.setOpusResultTable(opusResultTable);

        //专家称号
        ExpertInfoTable expertInfoTable = new ExpertInfoTable();
        List<ExpertTitleVo> expertTitleVos = data.getExpertTitleVos();
        List<RowRenderData> expertRowList = new ArrayList<>();
        if(expertTitleVos != null && expertTitleVos.size() > 0){
            for(int i=expertTitleVos.size()-1;i>=0;i--){
                if(expertTitleVos.get(i).getIsHide() == null || !(expertTitleVos.get(i).getIsHide().equals("0"))) {
                    String acquTime = "";
                    if (expertTitleVos.get(i).getAcquTime() != null) {
                        acquTime = sdf.format(expertTitleVos.get(i).getAcquTime());
                    }
                    RowRenderData row = RowRenderData.build(
                            new TextRenderData(acquTime, textStyle),
                            new TextRenderData(expertTitleVos.get(i).getHonorName(), textStyle),
                            new TextRenderData(expertTitleVos.get(i).getConferUnit(), textStyle));
                    row.setRowStyle(rowStyle);
                    expertRowList.add(row);
                }
            }
        }
        expertInfoTable.setExpertInfos(expertRowList);
        datas.setExpertInfoTable(expertInfoTable);

        //近三年绩效
        ThreeYearTable threeYearTable = new ThreeYearTable();
        List<YearEffectVo> yearEffectVos = data.getYearEffectVos();
        List<RowRenderData> yearRowList = new ArrayList<>();
        if(yearEffectVos != null && yearEffectVos.size() > 0){
            for(int i=yearEffectVos.size()-1;i>=0;i--){
                RowRenderData row = RowRenderData.build(
                        new TextRenderData(yearEffectVos.get(i).getYear()+"", textStyle),
                        new TextRenderData(yearEffectVos.get(i).getPerforGrade(), textStyle));
                row.setRowStyle(rowStyle);
                yearRowList.add(row);
            }
        }
        threeYearTable.setThreeYears(yearRowList);
        datas.setThreeYearTable(threeYearTable);

        try {
            //获取头像
            TouXiangVo iamges = getTouXiang(erpNo);
            if(iamges != null && iamges.getInputStream()!=null){
                datas.setPic(new PictureRenderData(100, 160,".jpg",
                        iamges.getInputStream()));
            }
            ClassPathResource resource = new ClassPathResource("/templates/competent_report_form.docx");
            inputStream = resource.getInputStream();
            Configure config = Configure.newBuilder().bind("work_status_table", new WorkStatusTablePolicy())
                    .bind("educate_info_table", new EducateTablePolicy()).bind("study_train_table", new StudyTrainTablePolicy())
                    .bind("work_info_table", new WorkInfoTablePolicy()).bind("work_result_table", new WorkResultTablePolicy())
                    .bind("opus_result_table", new OpusResultTablePolicy()).bind("expert_info_table", new ExpertInfoTablePolicy())
                    .bind("three_year_table", new ThreeYearTablePolicy()).build();
            template = XWPFTemplate.compile(inputStream,config).render(datas);
            String tempfilePath= UUID.randomUUID() +".docx";
            out = new FileOutputStream(tempfilePath);
            template.write(out);
            out.flush();
            responseWord(response,tempfilePath,filename);
            //删除临时文件
            file = new File(tempfilePath);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if (out!=null){
                    out.close();
                }
                if (template!=null){
                    template.close();
                }
                if (file != null) {// 删除临时文件
                    if(file.exists()){
                        file.delete();
                    }
                }
            }catch (Exception e){
                log.error("关闭异常",e);
            }
        }
    }

    static SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyyMMddHHmmss");

    private void responseWord(HttpServletResponse response,String path,String filename){
        File file = null;
        InputStream in = null;
        ServletOutputStream out = null;
        try{
            String downloadFileName=filename+simpleDateFormat.format(new Date())+".docx";
            file = new File(path);
            in = new FileInputStream(file);
            response.setCharacterEncoding("utf-8");
            response.setHeader("Cache-Control", "");
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment;filename="
                    .concat(String.valueOf(URLEncoder.encode(downloadFileName, "UTF-8"))));
            out = response.getOutputStream();
            byte[] buffer = new byte[512];
            int bytesToRead = -1;
            // 用响应对象response中的输出流读取生成好的文件
            while ((bytesToRead = in.read(buffer)) != -1) {
                out.write(buffer, 0, bytesToRead);
            }
            out.flush();
        }catch (Exception ex){
            log.error("product word fail..",ex);
        }finally {
            if (in != null) {
                try {
                    in.close();
                    if (out != null) {
                        out.close();
                    }
                } catch (IOException e) {
                    log.error("删除删除临时文件出错:" + e);
                }
            }
        }
    }

    /**
     * 获取头像
     * @param erpNo
     * @return
     */
    public TouXiangVo getTouXiang(String erpNo){
        TouXiangVo touXiangVo = null;
        InputStream inputStream = null;
        String fileId=null;
        String name=null;
        //通过ERP号查询头像Id
        ResultData resultData = fileServerCall.findFileList("personManage",erpNo,"userHead");
        JSONArray jsonArray =null;
        JSONObject obj =null;
        if(null != resultData) {
            log.info("获取头像数据为--"+resultData.toString());
            if(null != resultData.getData()) {
                jsonArray = JSONArray.fromObject(resultData.getData());
                if((null != jsonArray)&&(0 < jsonArray.size())) {
                    for(int i=0;i<jsonArray.size();i++) {
                        obj = (JSONObject) jsonArray.get(i);
                        if(null != obj) {
                            fileId = obj.getString("id");
                            name = obj.getString("oldFileName");
                        }
                    }
                }
            }
        }
        //下载文件
        if(fileId != null){
            try {
                Response response = fileServerCall.downloadFile(fileId);

                //判断是否下载成功
                if(response.status()==200) {
                    Response.Body body = response.body();
                    inputStream = body.asInputStream();
//                    inputStream = new FileInputStream(new File("test_one.png"));
                    touXiangVo = new TouXiangVo();
                    touXiangVo.setName(name);
                    touXiangVo.setInputStream(inputStream);
                }

            }catch (Exception e){
                log.error("下载文件失败！", e);
            }

        }

        return touXiangVo;
    }


}
